package net.mymilkedeek.ludum.tinythumb.states;

import net.mymilkedeek.ludum.tinythumb.*;
import net.mymilkedeek.ludum.tinythumb.Game;
import net.mymilkedeek.ludum.tinythumb.model.Battaljar;
import net.mymilkedeek.ludum.tinythumb.model.PartyFactory;
import net.mymilkedeek.ludum.tinythumb.model.Player;
import net.mymilkedeek.ludum.tinythumb.util.Constants;
import net.mymilkedeek.ludum.tinythumb.util.URL;
import org.newdawn.slick.*;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.util.Log;

import java.util.List;

/**
 * TODO: Write Documentation
 *
 * @author Michael Demey
 */
public class MainGameState extends BasicGameState {

    private CollisionMap cMap;
    private ActionSpace actionSpace;

    private Player player;
    private Image text;
    private Image speaker;
    private Animation talkingArrow;
    private Image moon;

    private float translateX = Constants.center_screen_x * -1;
    private float translateY = Constants.center_screen_y * -1;

    private boolean talking = false;
    private boolean joinedParty = false;

    private Music backgroundMusic;
    public boolean boss1 = false;
    public boolean boss2 = false;

    private Sound nope;
    private Sound doef;
    private Sound healfx;

    @Override
    public int getID() {
        return net.mymilkedeek.ludum.tinythumb.Game.S_MAIN;
    }

    @Override
    public void init(GameContainer gameContainer, StateBasedGame stateBasedGame) throws SlickException {
        Log.debug("MAINGAME   - Initializing");
        cMap = new CollisionMap();
        cMap.setTiledMap(MapFactory.getMap(MapFactory.start));

        player = new Player((cMap.getTiledMap().getWidth() * 32) - 320, (cMap.getTiledMap().getHeight() * 32) - 320);
        text = new Image("/resources/text/text.png");
        speaker = new Image("/resources/text/thumb.png");
        talkingArrow = new Animation(new SpriteSheet("/resources/text/arrow.png", 50, 50), 500);

        moon = new Image("/resources/spritesheets/moon.png");

        actionSpace = new ActionSpace();
        actionSpace.init(getInteractionId());
        talking = true;

        backgroundMusic = new Music("/resources/music/recording3.wav");

        nope = new Sound(URL.sfx_nope);
        doef = new Sound(URL.sfx_doef);
        healfx = new Sound(URL.sfx_heal);

        oldTime = System.currentTimeMillis();
    }

    private boolean moonB = false;

    @Override
    public void render(GameContainer gameContainer, StateBasedGame stateBasedGame, Graphics graphics) throws SlickException {
        //graphics.translate(translateX, translateY);
        if (event != null) {
            if (event.equalsIgnoreCase("moon")) {
                moonB = true;
            } else {
                moonB = false;
            }
        }
        if ( moonB) {
            moon.draw(0, 0);
        } else {
            cMap.getTiledMap().render(0, 0, (int) ((player.getPolygon().getX() / 32) - (Constants.screen_width / 2) / 32) + 1, (int) ((player.getPolygon().getY() - (Constants.screen_height / 2)) / 32) + 1, 11, 9);

            player.render(gameContainer, stateBasedGame, graphics);

        }
        if (!joinedParty) {
            new Image(URL.chicken_sprite).draw(Constants.center_screen_x - 32, Constants.center_screen_y);
        }

        if (talking) {
            actionSpace.render(gameContainer, stateBasedGame, graphics);
        }
    }

    private long oldTime;

    @Override
    public void update(GameContainer gameContainer, StateBasedGame stateBasedGame, int delta) throws SlickException {
        Input input = gameContainer.getInput();

        if (!backgroundMusic.playing()) {
            backgroundMusic.play();
        }

        if (boss1) {
            Battaljar.victory = false;
            Battaljar.party2 = PartyFactory.gnomeUp();
            PartyFactory.gnomeB = false;
            backgroundMusic.pause();
            stateBasedGame.enterState(Game.S_BATTL);
        }

        if (boss2) {
            Battaljar.victory = false;
            Battaljar.party2 = PartyFactory.foot();
            PartyFactory.footB = false;
            backgroundMusic.pause();
            stateBasedGame.enterState(Game.S_BATTL);
        }

        if (!talking && joinedParty) {
            if (input.isKeyDown(Input.KEY_LEFT) || input.isKeyDown(Input.KEY_RIGHT) || input.isKeyDown(Input.KEY_UP) || input.isKeyDown(Input.KEY_DOWN)) {
                float oldPositionX = player.getXcoord();
                float oldPositionY = player.getYcoord();

                player.update(gameContainer, stateBasedGame, delta);

                if (collision()) {
                    player.setXcoord(oldPositionX);
                    player.setYcoord(oldPositionY);
                    doef.play();
                }

                if (event()) {
                    talking = true;
                    Log.debug(" event name = " + event);
                }

                Log.debug("" + (System.currentTimeMillis() - oldTime));

                if (System.currentTimeMillis() - oldTime > 500) {
                    oldTime = System.currentTimeMillis();
                    double random = Math.random();
                    random *= 1000000;

                    Log.debug(random + "");

                    if (random > 665544) {
                        backgroundMusic.pause();
                        stateBasedGame.enterState(Game.S_BATTL);
                    }
                }
            }

            if (!talking) {

                if (input.isKeyPressed(Input.KEY_P)) {
                    stateBasedGame.enterState(Game.S_PARTY);
                }

                if (input.isKeyPressed(Input.KEY_H)) {
                    if (Heal.uses > 0) {
                        Battaljar.party1.getMember1().hp += 100;
                        Battaljar.party1.getMember2().hp += 100;
                        Heal.uses--;
                        healfx.play();
                    } else {
                        nope.play();
                    }
                }

                if (input.isKeyPressed(Input.KEY_B)) {
                    Battaljar.victory = false;
                    BattleState b = (BattleState) stateBasedGame.getState(Game.S_BATTL);
                    b.setBattleOver(false);
                    backgroundMusic.pause();
                    stateBasedGame.enterState(Game.S_BATTL);
                }
            }
        }

        if (talking) {
            if (event != null) {
                if (!event.equals(actionSpace.currentString)) {
                    actionSpace.init(event);
                }
            }
        }

        if (input.isKeyPressed(Input.KEY_SPACE)) {
            if (getInteractionId() != null) {
                if (!talking) {
                    Log.debug("if not talking 1");
                    actionSpace.init(getInteractionId());
                }
                Log.debug("update dem actionspace");
                talking = actionSpace.update(gameContainer, stateBasedGame, delta);

                if (!talking) {
                    Log.debug("if not talking 2");
                    joinedParty = true;
                }

                if (!talking && event()) {
                    endEvent(event);
                }
            }
        }

        if (input.isKeyPressed(Input.KEY_R)) {
            stateBasedGame.enterState(Game.S_GAMEOVER);
        }

        if (input.isKeyPressed(Input.KEY_F1)) {
            stateBasedGame.enterState(Game.S_HELP);
        }
    }

    private boolean event() {
        List<EventCollision> collisions = cMap.getEvents();
        for (EventCollision c : collisions) {
            if (c.active) {
                if (player.getPolygon().intersects(c.getPolygon())) {
                    Log.debug("EVENT");
                    event = c.name;
                    return true;
                }
            }
        }
        return false;
    }

    private void endEvent(String name) {

        if (name.equals("gnome")) {
            boss1 = true;
        }

        if (name.equals("end")) {
            boss2 = true;
        }

        if ( name.equals("moon")) {
            moonB = false;
        }

        List<EventCollision> events = cMap.getEvents();
        for (EventCollision e : events) {
            Log.debug(" e " + (e == null));
            Log.debug(" e.name " + (e.name == null));
            Log.debug(" event " + (event == null));
            Log.debug(event);
            if (e.name.equals(event)) {
                e.active = false;
            }
        }
        event = null;
        talking = false;
    }

    private String event;

    private String getInteractionId() throws SlickException {
        Log.debug("getInteractionId ");

        if (event != null) {
            Log.debug("getInteractionId " + event);
            if (!actionSpace.currentString.equals(event)) {
                actionSpace.init(event);
            }
            return event;
        }

        if (!joinedParty) {
            Log.debug("getInteractionId " + "act-one");
            return "act-one";
        }

        int x = 0;
        int y = 0;

        Log.debug(player.getPolygon().getX() + " " + player.getPolygon().getY());

        switch (player.direction_faced) {
            case Constants.direction_bottom:
                y = (int) (player.getPolygon().getY() / 32) + 1;
                x = (int) (player.getPolygon().getX() / 32);
                break;
            case Constants.direction_left:
                x = (int) (player.getPolygon().getX() / 32) - 1;
                y = (int) (player.getPolygon().getY() / 32);
                break;
            case Constants.direction_right:
                x = (int) (player.getPolygon().getX() / 32) + 1;
                y = (int) (player.getPolygon().getY() / 32);
                break;
            case Constants.direction_top:
                y = (int) (player.getPolygon().getY() / 32) - 1;
                x = (int) (player.getPolygon().getX() / 32);
                break;
        }
        String name = cMap.getCharacters().get(new Coord(x + 1, y + 1));

        Log.debug(x + " " + y + " " + name);
        return name;
    }

    private boolean collision() {
        List<Collision> collisions = cMap.getCollisions();
        for (Collision c : collisions) {
            if (player.getPolygon().intersects(c.getPolygon())) {
                Log.debug("COLLISION");
                return true;
            }
        }
        return false;
    }

    public void reset(GameContainer gameContainer, StateBasedGame stateBasedGame) throws SlickException {
        init(gameContainer, stateBasedGame);
    }
}